<?
/**
 * VoiceOne Settings/Plugin/manage
 *
 * Frontend to provide access to the plugin system in voiceone.
 * Allows to manage plugins: Activate/Deactivate, Delete, and Export/Import.
 * Multiple versions of the same plugin can exist in parallel, but only one version can be activ at a time.
 * Messages are written into DIV elements via xajax, thus avoiding classic post/get via forms except uploads.
 * @author Wolfgang Alper
 * @package voiceone
 * @subpackage settings_plugin
 */
  
include ("../../../admin/config/cfg.php");
global $cwlang, $cwLanguage, $absBasePath, $absPluginPath;
require_once("$absBasePath/lib/xajax/xajax.inc.php");
  
// ===================== xajax main functions start =================================

/**
 * xajax - Show Info about the selected plugin. 
 * 
 * Offers Download Link and a close Link
 * @param string $area DIV element to use for display
 * @param string $pluginPackage name of pluginPackage
 * @param integer $state  1=enable 0=disable
 * @see showPluginContent
 * @return xajax getXML
 */
function showPluginInfo($area, $plugin, $state) {
  
  $objResponse = new xajaxResponse();
  
  if ($state == 0) {
    // we just need to  hide the details
    $objResponse->addAssign($area, "innerHTML", "");
    $objResponse->addAssign($area, "style.display", "none");
    return $objResponse->getXML();
  }
  
  // read the plugin information
  // return arr[pluginpackage][xml2array structure]
  $ret = readPluginInfo($plugin);
  $pli = xmlArray2Hash($ret[$plugin][0]['elements']);  
  
  // get download URL. becaues we get an array back, we need to add a 2nd step.
  $ret = readPluginArchiveURL($plugin);
  $plURL = $ret[$plugin];
  
  $msg = <<<EODHeader
  <center><strong><p>Info about Plugin: {$pli['packageName']} - <a href="$plURL"> Download</a></p></strong></center>
  
  <table cellspacing="0">  
    <tr><td><strong>Label:</strong></td><td>{$pli['label']}</td></tr>
    <tr><td><strong>Short Name:</strong></td><td>{$pli['name']}</td></tr>
    <tr><td><strong>Full Name:</strong></td><td>{$pli['packageName']}</td></tr>
    <tr><td><strong>Version:</strong></td><td>{$pli['version']}</td></tr>
    <tr><td><strong>Date:</strong></td><td>{$pli['date']}</td></tr>
    <tr><td><strong>Description:</strong></td><td>{$pli['description']}</td></tr>
    <tr><td><strong>Author Name:</strong></td><td>{$pli['authorName']}</td></tr>
    <tr><td><strong>Author Email:</strong></td><td>{$pli['authorEmail']}</td></tr>
    <tr><td><strong>Author Website:</strong></td><td>{$pli['authorWebsite']}</td></tr>
    <tr><td><strong>Plugin Archive MD5:</strong></td><td>{$pli['md5']}</td></tr>
    <tr><td><strong>VoiceOne Version:</strong></td><td>{$pli['voVersion']}</td></tr>
    <tr><td><strong>Pluginsystem Version:</td><td>{$pli['voPlVersion']}</td></tr>
    <tr><td><strong>Objects included:</td><td>{$pli['elementCount']}</td></tr>
  </table>
  <br />  
EODHeader;


  $msg .= '<center><table cellspacing="0" border="1">';
  $msg .= '<tr><th colspan="2"><center><strong>' . "Included Files" . '</strong></center></th></tr>';
  $msg .= '<tr><th><strong>' . "Filename" . '</strong></th><th><strong>' . "MD5" . '</strong></th></tr>';
  // get attached files
  foreach ($pli['content'] as $files=>$fileRoot) {
    $plc = xmlArray2Hash($fileRoot['elements']);     
    $msg .= "<tr><td>{$plc['filename']}</td><td>{$plc['md5']}</td></tr>";
  }
  $msg .= '</table></center>';

  $msg .= <<<EODFooter
  <br /> 
<center>
    <a href="#" onclick="xajax_showPluginInfo('$area', '', 0); return false;">Close</a>
</center>
EODFooter;


  // show the info
  $objResponse->addAssign($area, "innerHTML", $msg);
  $objResponse->addAssign($area, "style.display", "");
  // jump to top
  $objResponse->addScript("scroll(0,300);");

  
  return $objResponse->getXML(); 
}




/**
 * xajax - Show Content of the selected plugin. 
 * 
 * Offers Download Link and a close Link
 * @param string $area DIV element to use for display
 * @param string $pluginPackage name of pluginPackage
 * @param integer $state  1=enable 0=disable
 * @see showPluginInfo
 * @return xajax getXML
 */
function showPluginContent($area, $plugin, $state) {
  
  $objResponse = new xajaxResponse();
  
  if ($state == 0) {
    // we just need to  hide the details
    $objResponse->addAssign($area, "innerHTML", "");
    $objResponse->addAssign($area, "style.display", "none");
    return $objResponse->getXML();
  }
  
  // get download URL. becaues we get an array back, we need to add a 2nd step.
  $ret = readPluginArchiveURL($plugin);
  $plURL = $ret[$plugin];
  
  $msg = <<<EODHeader
  <center><strong><p>Content of Plugin: {$plugin} - <a href="$plURL"> Download</a></p></strong></center>
  <br />
EODHeader;
  
  $msg .= '<center><table cellspacing="0" border="1">';
  //$msg .= '<tr><th colspan="3"><center><strong>' . "Content" . '</strong></center></th></tr>';
  $msg .= '<tr><th><strong>' . "Type" . '</strong></th><th><strong>' . "Name" . '</strong></th><th><strong>' . "Label" . '</strong></th></tr>';

  // get attached files
  // return arr[pluginpackage][xml2array structure]
  $ret = readPluginData($plugin);  
  foreach ($ret[$plugin][0]['elements'] as $content=>$contentRoot) {
    $plc = xmlArray2Hash($contentRoot['elements']);     
    $msg .= "<tr><td>{$contentRoot['name']}</td><td>{$plc['name']}</td><td>{$plc['label']}</td></tr>";
  }  
  $msg .= '</table></center>';

  $msg .= <<<EODFooter
  <br /> 
<center>
    <a href="#" onclick="xajax_showPluginContent('$area', '', 0); return false;">Close</a>
</center>
EODFooter;


  // show the details
  $objResponse->addAssign($area, "innerHTML", $msg);
  $objResponse->addAssign($area, "style.display", "");
  // jump to top
  $objResponse->addScript("scroll(0,300);");

  
  return $objResponse->getXML(); 
}

/**
 * xajax - Show an alert / info message on in a specific DIV by enabling that div
 *
 * @param integer $type defined as constant. Can be GOOD or BAD
 * @param string $div ID of DIV element
 * @param string $msg content that is written to the innerHTML attribute
 * @return xajax getXML
 */
function setAlert($type, $msg, $div="alertInfo") {

  $objResponse = new xajaxResponse();
  
  switch ($type) {
    case GOOD:
      $style = "AlertGood";
    break;
    
    case BAD:
      $style = "AlertBad";
    break;
  }
  
  $objResponse->addAssign($div, "className", $style);
  $objResponse->addAssign($div, "style.display", "");
  $objResponse->addAssign($div, "innerHTML", $msg);
  
  return $objResponse->getXML(); 
}



/**
 * xajax - read plugin cache directory and plugin database for installed plugins and write elements to a table
 *
 * @param string $tableID ID to add rows for each plugin
 * @return xajax getXML
 * @todo put formatting in stylesheet
 */
function showPlugins($tableID) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();


  // need a tbody element to get IE to work!
  $tableBodyID = $tableID."Body";
  $objResponse->addCreate($tableID, "tbody", $tableBodyID);
  
  // build the table rows
  // use unique id's for DOM elements. Very important for IE to work!
  $id = "";
  $prefixRow="dataPluginList-";

  // read the plugin information for each plugin
  // return arr[pluginpackage][0][xmlarray structure]. I.e. arr['wake_up-call.1.1.10][0]['label']='plugininfo'
  $plArr=readPluginInfo("");
  
  foreach ($plArr as $plugin=>$plRoot) {
    
    // convert the xmlarray structure to a simple hash with unique keys
    $pli = xmlArray2Hash($plRoot[0]['elements']);
        
    // create some vars to make the code easier readable    
    // use pluginPackage as id because non-activated plugins do not have a unique id
    $id = $plugin;

    $plName = $pli['name'];
    $plLabel = $pli['label'];
    $plVersion = $pli['version'];
    $plDate = $pli['date'];
    $plAuthorName = $pli['authorName'];
    $plDescription = $pli['description'];
    $plState = $pli['state'];
    $ret = readPluginArchiveURL($plugin);
    $plURL = $ret[$plugin];
    
    // Create new row. We use $plPackageName as part of the id for new DOM elements    
    $objResponse->addCreate($tableBodyID, "tr", $prefixRow.$id);
    $objResponse->addAssign($prefixRow.$id, "className", "firstofgroup rule");
    
    // here we create the td elements und send them via xajax to the browsers DOM tree.
    // this would allow modification of each entry if required at any time.
    
    // delete a plugin (show link via icon)
    $prefixData = "del-";
    $ldel = "<a href=\"#\" onclick=\"xajax_deletePlugin('" . $plugin . "'); return false;\">";
    $ldel = "<a href=\"#\" onclick=\"if (confirm('Are your sure to delete Plugin?')) {xajax_deletePlugin('" . $plugin . "'); return false;} else return false;\">";
    
    
    $ldel.= "<img src=\"/voiceone/admin/public/img/icon_remove.gif\" alt=\"Delete\" />";
    $ldel.= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $ldel);
    
    // content of plugin (show link via icon)
    $prefixData = "infoIcon-";
    $linfo = "<a href=\"#\" onclick=\"xajax_showPluginContent('pluginDetails', '" . $plugin . "', 1); return false;\">";
    $linfo .= "<img src=\"/voiceone/admin/public/img/idea.gif\" alt=\"Info\" />";
    $linfo .= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
    
    // download a plugin (show link via icon)
    $prefixData = "dl-";
    $ldl = "<a href=\"" . $plURL . "\">";
    $ldl .= "<img src=\"/voiceone/admin/public/img/icon_download.png\" alt=\"Info\" />";
    $ldl .= "</a>"; 
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $ldl);
  
    // Create Label as link to info of plugin
    $prefixData = "infoLabel-";
    $linfo = "<a href=\"#\" onclick=\"xajax_showPluginInfo('pluginDetails', '" . $plugin . "', 1); return false;\">";
    $linfo .= $plLabel;
    $linfo .= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);

    // Version and date of plugin
    $linfo = '<SPAN STYLE="font-size: 100%; font-weight:bold; white-space:nowrap;">' . $plVersion . '</SPAN>' . '<br />';
    $linfo .= '<SPAN STYLE="font-size: 75%; font-weight:normal; white-space:nowrap;">' . $plDate . '</SPAN>';
    $prefixData = "version-";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);

    // AuthorName of plugin
    $prefixData = "authorName-";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $plAuthorName);

    // Description of plugin
    $prefixData = "description-";
    $msg = '<SPAN STYLE="font-size: 80%; font-weight:normal;">';
    $msg .= $plDescription;
    $msg .= '</SPAN>';
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $msg);

    // Create Label as link to activate / deactivate a plugin
    $prefixData = "activate-";
    if ($plState == STATE_SELECTED) {
      // plugin is activ
      $linfo = "Activ<br />"; 
      $linfo .= "<a href=\"#\" onclick=\"xajax_deactivate('" . $plugin . "'); return false;\">";
      $linfo .= "Deactivate";
      $linfo .= "</a>";
      $className = "green";
    } else { 
      // plugin is inactiv
      $linfo = "Inactiv<br />"; 
      $linfo .= "<a href=\"#\" onclick=\"xajax_activate('" . $plugin . "'); return false;\">";
      $linfo .= "Activate";
      $linfo .= "</a>";
      $className = "red";
    }
  
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "className", $className);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
    
  }
  return $objResponse->getXML(); 
}



/**
 * xajax - Delete a plugin from cache and from database
 * 
 * @param string $pluginPackage
 * @return xajax getXML
 * @todo add "do you really want to delete..." and get returncodes from deactivation 
 */
function deletePlugin($plugin) {

  global $cwlang, $asterisk;

  $objResponse = new xajaxResponse();
  
  // deactivate the plugin first
  $ret = $asterisk->getPluginByPackageName($plugin);
  if (count($ret)) {
    // plugin is activated, so deactivate first
    $plId = $ret[0]['id'];
    $ret = $asterisk->delPlugin($plId);
  }
  
  
  // remove the cache and the archive
  if (deletePluginCache($plugin) > 0) {
    $msg = "<strong>" . T_("Plugin deleted successful") . "</strong>" . ": " . $plugin;
    $objResponse->loadXML(setAlert(GOOD, $msg, "alertInfo"));
    $objResponse->addRemove("dataPluginList-" . $plugin);
  } else {
    $msg = "<strong>" . T_("Plugin not deleted") . "</strong>" . ": " . $plugin;
    $objResponse->loadXML(setAlert(BAD, $msg, "alertInfo"));
  }
  
  return $objResponse->getXML(); 
}

/**
 * xajax - activate a plugin
 *
 * @param string $plugin 
 * @return xajax getXML
 * @todo implement errorhandling
 * @see deactivate
 */
function activate($plugin) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();
  
  // check wether this plugin is already installed in a different version
  $ret = readPluginInfo($plugin);
  $pli = xmlArray2Hash($ret[$plugin][0]['elements']); 
  $ret = $asterisk->getPluginByName($pli['name']);
  if  (count($ret)) {
    $msg = "Plugin is already installed in version:" . $ret[0]['version'] . ". " . "Please deactivate first.";
    $objResponse->addAlert($msg);
    return $objResponse->getXML();
  }
  
  // allow to install new plugin or to reactivate an installed plugin in the same version
  $pi = readPluginInfoAsXML($plugin); 
  $pc = readPluginDataAsXML($plugin); 
  $ret = $asterisk->putPlugin($pi, $pc);
  
  if ($ret > 0) {
    $msg = "<strong>" . T_("Plugin activated successful") . "</strong>" . ': ' . $plugin;  
    $objResponse->loadXML(setAlert(GOOD, $msg)); 
    // plugin is activ, change table
    $linfo = "Activ<br />"; 
    $linfo .= "<a href=\"#\" onclick=\"xajax_deactivate('" . $plugin . "'); return false;\">";
    $linfo .= "Deactivate";
    $linfo .= "</a>";    
    $className = "green";     
    $prefixData = "activate-";
    $id = $plugin;
    $objResponse->addAssign($prefixData.$id, "className", $className);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);    
  } else {
    $msg = "<strong>" . T_("Plugin not activated") . "</strong>" . ': ' . $plugin . '<br />';
    $msg .= T_("Contact the administrator. Ask to check the database, the plugin cache directory and the archive.");
    $objResponse->loadXML(setAlert(BAD, $msg));     
  }
      
  return $objResponse->getXML(); 
}


/**
 * xajax - deactivate a plugin
 *
 * @param string $plugin 
 * @return xajax getXML
 * @todo implement errorhandling
 * @see activate
 */
function deactivate($plugin) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();
  
  $ret = $asterisk->getPluginByPackageName($plugin);
  if (!count($ret)) {
    // something went wrong. should not happen
    $msg = "<strong>" . T_("Error while deactiving Plugin") . ': ' . $plugin . "<br>" . T_("Please check your database.") . "</strong>";
    $objResponse->loadXML(setAlert(BAD, $msg));
    return $objResponse->getXML(); 
    
  }
  $plId = $ret[0]['id'];
  $ret = $asterisk->delPlugin($plId);
  if ($ret <= 0) {
    // something went wrong. should not happen
    $msg = "<strong>" . T_("Error while deactiving Plugin") . ': ' . $plugin . "<br>" . T_("Please check your database.") . "</strong>";
    $objResponse->loadXML(setAlert(BAD, $msg));
    return $objResponse->getXML(); 
    
  }
  
  $msg = "<strong>" . T_("Plugin deactivated successful") . "</strong>" . ': ' . $plugin;
  $objResponse->loadXML(setAlert(GOOD, $msg));
  
  // plugin is inactiv
  $linfo = "Inactiv<br />"; 
  $linfo .= "<a href=\"#\" onclick=\"xajax_activate('" . $plugin . "'); return false;\">";
  $linfo .= "Activate";
  $linfo .= "</a>";
  $className = "red";
  $prefixData = "activate-";
  $id = $plugin;
  $objResponse->addAssign($prefixData.$id, "className", $className);
  $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
  
  return $objResponse->getXML(); 
}




/**
 * xajax - Init the page. Initialize elements
 *
 * @return xajax getXML
 */
function initPage($startMsg) {

  $objResponse = new xajaxResponse();
  
  // we put the alert message in the alertInfo div and on a page reload we check wether to enable it
  if ($startMsg != "") $objResponse->addAssign('alertInfo', "style.display", "");
  
  $objResponse->addAssign('pluginDetails', "style.display", "none");

  // check preferences
  // check if "which", "zip" and "unzip" are installed
  $msg = "";
  $ret = shell_exec("which which");
  if ($ret == "") {$msg = T_("Missing cmd WHICH on the system.")."<br />";}
  $ret = shell_exec("which zip");
  if ($ret == "") {$msg .= T_("Missing cmd ZIP on the system.")."<br />";}
  $ret = shell_exec("which unzip");
  if ($ret == "") {$msg .= T_("Missing cmd UNZIP on the system.")."<br />";}
  
  if ($msg != "") {
    $msg = T_("Plugin creation will not work!")."<br />" . $msg;
    $objResponse->loadXML(setAlert(BAD, $msg, "alertInfo"));
  }
  
  $objResponse->loadXML(showPlugins('tablePluginList'));
  
  return $objResponse->getXML(); 
}

// ===================== xajax main functions end ===================================

$xajax = new xajax();
//$xajax->debugOn();
// test
$xajax->registerFunction("importPlugin");
$xajax->registerFunction("testxml2array");

// main
$xajax->registerFunction("showPluginInfo"); // show details about a plugin in a DIV
$xajax->registerFunction("showPluginContent"); // show Content about a plugin in a DIV
$xajax->registerFunction("showPlugins"); // list available plugins from cache and allow to manage
$xajax->registerFunction("setAlert"); // set Alert and Info Messages
$xajax->registerFunction("deletePlugin"); // delete a plugin from cache and from database if necessary
$xajax->registerFunction("activate"); // activate a plugin
$xajax->registerFunction("deactivate"); // deactivate a plugin
$xajax->registerFunction("initPage"); // init the page




$xajax->processRequests();
  
// *********************************** xajax functions end ***********************************
   
   //================ PAGE LOGIC ================
   
   // get alert msg as stored in session var whith result of upload
   $alert=getAlert();

  //upload a plugin. Need to use regular POST because javascript (and therefore xajax) has no access to local filesystem
  if ($_POST["act"]=="upload") {
    $ftmp = $_FILES['filename']['tmp_name'];
    $fname = $_FILES['filename']['name'];
    errArr($_FILES);
    $ret = array();
    //Basic test wether the file is a plugin. "application/zip" would be MIME confirm but is not always used ;-(
    $validTypes = array("application/zip", "application/x-zip", "application/x-compressed", "application/x-zip-compressed");
    foreach ($validTypes as $vt) {
      if ($_FILES["filename"]["type"] == $vt) {
        // use a temp name that wont exists as a real pluginfile
        $myfile = "newUploadedVOPlugin.zip";
        if (move_uploaded_file($ftmp, $absPluginPath.$myfile)) {
          // unpack and validate the package archive
          $ret = createPluginCachefromArchive($myfile);
          break;
        }
      }
    }
    
    // handle the result of createPluginCachefromArchive($myfile)
    if ($ret['state'] == true) {
      $alert = "<div class=\"AlertGood\">" . $ret['msg'] . "</div>";
    }
    else {
      $alert = "<div class=\"AlertBad\">" . $ret['msg'] . "</div>";
    }
    // Store $alert in _SESSION['alert'] to have it available after rebuilding the page and execute    
    goToMainPage($alert,"./");
    
  } // post upload
    
//================ MAIN CONTENTS ================
  ob_start();
  $sel="manage"; include("../navigation.php");
  $xajax->printJavascript("../../../admin/lib/xajax/");
  ?>
  
  <!-- add javascript xajax helper functions -->
  <script type="text/javascript" src="../../../admin/lib/xajaxextend/xajaxextend.js"></script>

  <!-- show AlertGood or AlertBad type messages via xajax. Default is not-visible -->
  <!-- add $alert as returned with a message when doing an upload -->
  <div id="alertInfo" style="display: none"><?=$alert?></div>
  
  <div class="SectionHeader">
    <h1><?=T_("Manage Plugins")?></h1>
  </div>
  <p class="blockintro"><?=T_("<h1>The following options are available via the plugin system</h1>
  <h2>Manage existing plugins:</h2>
  <ul>
    <li>Activate/ Deactivate a plugin</li>
    <li>Delete a Plugin</li>
    <li>Export a Plugin</li>
    <li>Import a Plugin</li>
    <li>Get information about a plugin</li>
  </ul>
  <h2>Create new plugins:</h2>
  <ul>
    <li>Create plugin from scratch</li>
    <li>Create plugin from existing plugin</li>
  </ul>")?></p>


  <!-- form import upload a plugin -->
  <div id="basic_form">
  <form name="uploadPlugin" id="uploadPlugin" enctype="multipart/form-data" action="<?=$PHP_SELF?>" method="post">
    <h2><?=T_("Import a plugin")?></h2>
      <div class="block">
      <table>
        <tr>
          <td><input type="file" name="filename" size="60" />&nbsp;<input type="submit" value="Send" size="10"/></td>
        </tr>  
      </table>
    </div>
    <input type="hidden" name="act" value="upload" />
  </form>
  </div>
  
  <!-- show plugin details on request. Default is not visible-->
  <div id="pluginDetails" class="AlertGood" style="display: none"></div>
  
  <div class="block">
    <table id="tablePluginList" cellspacing="0" class="todolist">
      <!-- tbody tag is essential to get IE to work! when adding TR elements. Created via xajax so not here -->
        <tr id="headerPluginList">
          <th colspan="3"><?=T_("Action")?></th>
          <th><?=T_("Name")?></th>
          <th><?=T_("Version")?></th>
          <th><?=T_("Author")?></th>
          <th><?=T_("Description")?></th>
          <th><?=T_("State")?></th>
        </tr>
    </table>
  </div>
  
  <?
  $contents=ob_get_contents();
  ob_end_clean();
  ?>
      
  <?
  //================ SIDEBAR ================
  ob_start(); 
  ?>
  <div class="Sidebar">
    <h1><?=T_("Information")?></h1>
    <p><?=T_("<h2>The following Options are available:<h2>
<ul>
  <li>Activate/ Deactivate a plugin</li>
  <li>Delete a Plugin</li>
  <li>Export a Plugin via Download</li>
  <li>Import a Plugin via Upload</li>
  <li>Get information about a plugin</li>
  <li>Get information about the content of a plugin</li>
</ul>
<h1>Note:</h1>
<p>Do not forget to adjust Speeddials when importing applications and the like</p>")?></p>
  </div>
  <?  
  $sidebar=ob_get_contents();
  ob_end_clean();

  //================ SETTINGS ================

  $smarty->assign("section", "plugin");
  $smarty->assign("subsection", "");
  $smarty->assign("templateType", "TwoColLeft");  //OneCol, TwoColLeft, TwoColRight
  $smarty->assign("contents", $contents);
  $smarty->assign("sidebar", $sidebar);
  $smarty->display('settings.tpl');
?>

  <!--  Init Page via xajax call -->
  <script>xajax_initPage('<?=$alert?>')</script>
  
  
